home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks97 / VUlites.sit / VUlites / source code / VUlites.cpp next >
C/C++ Source or Header  |  1997-06-28  |  6KB  |  331 lines

  1. #include "VUlites.h"
  2.  
  3. /*
  4. stuff we'll need to check and set up:
  5. PowerPC architecture
  6. sound manager version
  7. auto gain off
  8. asynchronous?
  9. uncompressed
  10. continuous recording on
  11. 44.1/16
  12. "quality"
  13. */
  14.  
  15. long mikeRefNum; // the RefNum of our input device
  16. SPB paramBlock; // sound parameter block
  17. Ptr soundBuffer;
  18. //Ptr soundBuffer2;
  19. long soundSetupBuffer[5];
  20. long lowThresh = 0x2000;
  21. long midThresh = 0x4800;
  22. long hiThresh = 0x6000;
  23. long lowCount = 0;
  24. long midCount = 0;
  25. long hiCount = 0;
  26. long number = 0;
  27. bool quit = false;
  28. bool requestToQuit = false;
  29. SICompletionUPP lightsUPP;
  30. long oldLightSetting = 0;
  31. bool adbDone = false;
  32. ADBCompletionUPP adbComp;
  33. DeferredTaskUPP defTask;
  34. DeferredTask taskRec;
  35. //int currentBuff = 0;
  36.  
  37. void main(void)
  38. {
  39.  
  40. // ----- Variables
  41.  
  42. OSErr error; // to catch an error we go
  43. EventRecord junkEvent;
  44.  
  45. // ----- Code
  46.  
  47. // Allocate buffers
  48.  
  49. soundBuffer = NewPtr(kBufferSize);
  50.  
  51. if (soundBuffer == NULL || MemError())
  52. {
  53.     //cout << "Cannot allocate buffer." << endl;
  54.     return;
  55. }
  56. /*
  57. soundBuffer2 = NewPtr(kBufferSize);
  58.  
  59. if (soundBuffer == NULL || MemError())
  60. {
  61.     //cout << "Cannot allocate buffer." << endl;
  62.     return;
  63. }
  64. */
  65. // Get our microphone
  66.  
  67. error = SPBOpenDevice("\p", // The name of the device. We want the default one.
  68.                       siWritePermission, // Permission? Do we need permission?
  69.                       &mikeRefNum); // And a refNum for the input device
  70.  
  71. //cout << "The refNum is " << mikeRefNum << "." << endl;
  72. if (error != noErr)
  73. {
  74.     //cout << "Error: " << static_cast<long>(error) << "." << endl;
  75.     return;
  76. }
  77.  
  78. if (mikeRefNum == 0 || error != noErr)
  79.     return;
  80.  
  81. // Set up stuff
  82.  
  83. soundSetupBuffer[0] = rate44khz;
  84. error = SPBSetDeviceInfo(mikeRefNum, siSampleRate, soundSetupBuffer);
  85. if (error != noErr)
  86. {
  87.     //cout << "Error: " << static_cast<long>(error) << "." << endl;
  88.     return;
  89. }
  90.  
  91. soundSetupBuffer[0] = 'NONE';
  92. error = SPBSetDeviceInfo(mikeRefNum, siCompressionType, soundSetupBuffer);
  93. if (error != noErr)
  94. {
  95.     //cout << "Error: " << static_cast<long>(error) << "." << endl;
  96.     return;
  97. }
  98.  
  99. soundSetupBuffer[0] = 1 << 16;
  100. error = SPBSetDeviceInfo(mikeRefNum, siNumberChannels, soundSetupBuffer);
  101. if (error != noErr)
  102. {
  103.     //cout << "Error: " << static_cast<long>(error) << "." << endl;
  104.     return;
  105. }
  106.  
  107. soundSetupBuffer[0] = 16 << 16;
  108. error = SPBSetDeviceInfo(mikeRefNum, siSampleSize, soundSetupBuffer);
  109. if (error != noErr)
  110. {
  111.     //cout << "Error: " << static_cast<long>(error) << "." << endl;
  112.     return;
  113. }
  114.  
  115. // Call, sleep
  116.  
  117. // Make up all these damned UPPs
  118.  
  119. lightsUPP = NewSICompletionProc(lights);
  120. adbComp = NewADBCompletionProc(ADBComp);
  121. defTask = NewDeferredTaskProc(DefTask);
  122.  
  123. // Set up the parameter block
  124.  
  125. paramBlock.inRefNum = mikeRefNum;
  126. paramBlock.count = kBufferSize;
  127. paramBlock.milliseconds = 0;
  128. paramBlock.bufferLength = kBufferSize;
  129. paramBlock.bufferPtr = soundBuffer;
  130. paramBlock.completionRoutine = lightsUPP;
  131. paramBlock.interruptRoutine = NULL;
  132. paramBlock.userLong = 0xd15c0L;
  133. paramBlock.error = noErr;
  134. paramBlock.unused1 = 0;
  135.  
  136. // Play that funky music, white boy!
  137.  
  138. SPBRecord(¶mBlock, 
  139.             TRUE); // asynchronous, please
  140.  
  141. while (quit == false)
  142. {
  143.     WaitNextEvent (0, &junkEvent, 0x60, nil);
  144. }
  145.  
  146. // Release the mike to someone else
  147.  
  148. error = SPBCloseDevice(mikeRefNum);
  149.  
  150. //if (error != noErr)
  151. //    cout << "Error: " << static_cast<long>(error) << "." << endl;
  152.  
  153. // Kill the UPPs
  154.  
  155. DisposeRoutineDescriptor(lightsUPP);
  156. DisposeRoutineDescriptor(adbComp);
  157. DisposeRoutineDescriptor(defTask);
  158.  
  159. }
  160.  
  161. asm long abs (long a)
  162. {
  163.     srawi r4, r3, 31
  164.     add r5, r4, r3
  165.     xor r3, r5, r4
  166. }
  167.  
  168. void lights (SPBPtr ignore1, Ptr ignore2, short ignore3, long ignore4)
  169. {
  170.  
  171. //DebugStr("\pLights;g");
  172.  
  173. long newLightSetting = 7;
  174.  
  175. if (requestToQuit)
  176. {
  177.     quit = true;
  178.     return;
  179. }
  180.  
  181. for (short *i = (short *)soundBuffer;
  182.      i < (short *)(soundBuffer + kBufferSize/sizeof(short));
  183.      i++)
  184. {
  185.     if (abs(*i) < lowThresh)
  186.     {
  187.         newLightSetting &= 0x07;
  188.     }
  189.     else if (abs(*i) < midThresh)
  190.     {
  191.         newLightSetting &= 0x06;
  192.     }
  193.     else if (abs(*i) < hiThresh)
  194.     {
  195.         newLightSetting &= 0x04;
  196.     }
  197.     else
  198.     {
  199.         newLightSetting &= 0x00;
  200.     }
  201. }
  202.  
  203. switch (newLightSetting)
  204. {
  205.     case 0:
  206.         hiCount++;
  207.         break;
  208.     case 4:
  209.         midCount++;
  210.         break;
  211.     case 6:
  212.         lowCount++;
  213.         break;
  214. }
  215.  
  216. number++;
  217.  
  218. //Re-evaluate the thresholds
  219.  
  220. if (number >= reevalThresh)
  221. {
  222.     if (hiCount < (reevalThresh / 4 * 3))
  223.     {
  224.         hiThresh -= 0x100;
  225.     }
  226.     else if (hiCount > (reevalThresh / 4 * 3))
  227.     {
  228.         hiThresh += 0x100;
  229.     }
  230.     
  231.     if (midCount < (reevalThresh / 2))
  232.     {
  233.         midThresh -= 0x100;
  234.     }
  235.     else if (midCount > (reevalThresh / 2))
  236.     {
  237.         midThresh += 0x100;
  238.     }
  239.     
  240.     if (lowCount < (reevalThresh / 4))
  241.     {
  242.         lowThresh -= 0x100;
  243.     }
  244.     else if (lowCount > (reevalThresh / 4))
  245.     {
  246.         lowThresh += 0x100;
  247.     }
  248.     
  249.     lowCount = 0;
  250.     midCount = 0;
  251.     hiCount = 0;
  252.     number = 0;
  253. }
  254.  
  255. // New light setting? Then update lights
  256.  
  257. if (newLightSetting != oldLightSetting)
  258. {
  259.     oldLightSetting = newLightSetting;
  260.  
  261.  
  262.     //Make deferred task
  263.     
  264.     taskRec.qType = dtQType;
  265.     taskRec.dtAddr = defTask;
  266.     taskRec.dtReserved = 0;
  267.     
  268.     DTInstall (&taskRec);
  269.  
  270. }
  271.  
  272. // Set up the parameter block
  273.  
  274. paramBlock.inRefNum = mikeRefNum;
  275. paramBlock.count = kBufferSize;
  276. paramBlock.milliseconds = 0;
  277. paramBlock.bufferLength = kBufferSize;
  278. paramBlock.bufferPtr = soundBuffer;
  279. paramBlock.completionRoutine = lightsUPP;
  280. paramBlock.interruptRoutine = NULL;
  281. paramBlock.userLong = 0xd15c0L;
  282. paramBlock.error = noErr;
  283. paramBlock.unused1 = 0;
  284.  
  285. // Play that funky music, white boy!
  286.  
  287. SPBRecord(¶mBlock, 
  288.           TRUE); // asynchronous, please
  289. }
  290.  
  291. void ADBComp (Ptr ignore1, Ptr ignore2, long ignore3)
  292. {
  293. adbDone = true;
  294. }
  295.  
  296. void DefTask (long ignore1)
  297. {
  298.  
  299. //DebugStr("\pDefTask;g");
  300.  
  301. char RegisterData[5];
  302. unsigned char command;
  303. OSErr myErr;
  304.  
  305. // Read
  306. adbDone = false;
  307. RegisterData[0] = 2;
  308. command = (0x02 * 16) + 0x0C + 0x02;
  309. myErr = ADBOp(nil, adbComp, RegisterData, command);
  310. do {} while (adbDone == 0);
  311. if (myErr != noErr)
  312. {
  313.     requestToQuit = true;
  314.     return;
  315. }
  316. // Set
  317. adbDone = false;
  318. RegisterData[2] &= (0xff - 0x07);
  319. RegisterData[2] |= oldLightSetting;
  320. command = (0x02 * 16) + 0x08 + 0x02;
  321. myErr = ADBOp(nil, adbComp, RegisterData, command);
  322. do {} while (adbDone == 0);
  323. if (myErr != noErr)
  324. {
  325.     requestToQuit = true;
  326.     return;
  327. }
  328.  
  329. }
  330.  
  331.